﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace GameDesigner
{
    /// <summary>
    /// Enables added functionality to program.
    /// </summary>
    static class PluginManager
    {
        public static List<System.Type> MovableObjects;

        static PluginManager()
        {
            MovableObjects = new List<System.Type>();
        }

        /// <summary>
        /// This functions goes through all know assembly paths and tries to load them (if not) and
        /// add their functionality into the GameDesigner.
        ///     Know Paths are:
        ///         1. ApplicationRoot\Plugin directory and it's subdirectories
        ///         
        ///     <b>Attention:</b> If an assembly is present in both root and plugins, the root one 
        ///     will take over.
        /// </summary>
        public static void LoadPlugins(string ApplicationRoot)
        {
            //go through all assemblies

            // 1. Already loaded assemblies
            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                LoadTypesInAssembly(assembly);
            }

            // 2. Plugins
            DirectoryInfo currentDirectory = new DirectoryInfo(ApplicationRoot + Path.DirectorySeparatorChar + "Plugins");
            foreach (FileInfo fileInfo in currentDirectory.GetFiles("*.dll"))
            {
                try
                {
                    Assembly assembly = Assembly.LoadFrom(fileInfo.FullName);
                    LoadTypesInAssembly(assembly);
                }
                catch
                { }
            }

            //TODO: load plugins in subfolders from Plugins
        }

        private static void LoadTypesInAssembly(Assembly assembly)
        {
            foreach (Type type in assembly.GetTypes())
            {
                //Load MovableObject Subclasses   
                if (type.IsSubclassOf(typeof(Axiom.Core.MovableObject)))
                {
                    MovableObjects.Add(type);
                }
                //Load any other needed types
            }
        }
    }
}
